﻿// Decompiled with JetBrains decompiler
// Type: UnityEngine.RectInt
// Assembly: UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E6AE6B5A-2752-4B07-9528-C8B77C62CE79
// Assembly location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
// XML documentation location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.xml

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine.Scripting;

#nullable disable
namespace UnityEngine
{
  /// <summary>
  ///   <para>A 2D Rectangle defined by x, y, width, height with integers.</para>
  /// </summary>
  [UsedByNativeCode]
  public struct RectInt : IEquatable<RectInt>, IFormattable
  {
    private int m_XMin;
    private int m_YMin;
    private int m_Width;
    private int m_Height;

    /// <summary>
    ///   <para>Left coordinate of the rectangle.</para>
    /// </summary>
    public int x
    {
      get => this.m_XMin;
      set => this.m_XMin = value;
    }

    /// <summary>
    ///   <para>Top coordinate of the rectangle.</para>
    /// </summary>
    public int y
    {
      get => this.m_YMin;
      set => this.m_YMin = value;
    }

    /// <summary>
    ///   <para>Center coordinate of the rectangle.</para>
    /// </summary>
    public Vector2 center
    {
      get
      {
        return new Vector2((float) this.x + (float) this.m_Width / 2f, (float) this.y + (float) this.m_Height / 2f);
      }
    }

    /// <summary>
    ///   <para>The lower left corner of the rectangle; which is the minimal position of the rectangle along the x- and y-axes, when it is aligned to both axes.</para>
    /// </summary>
    public Vector2Int min
    {
      get => new Vector2Int(this.xMin, this.yMin);
      set
      {
        this.xMin = value.x;
        this.yMin = value.y;
      }
    }

    /// <summary>
    ///   <para>The upper right corner of the rectangle; which is the maximal position of the rectangle along the x- and y-axes, when it is aligned to both axes.</para>
    /// </summary>
    public Vector2Int max
    {
      get => new Vector2Int(this.xMax, this.yMax);
      set
      {
        this.xMax = value.x;
        this.yMax = value.y;
      }
    }

    /// <summary>
    ///   <para>Width of the rectangle.</para>
    /// </summary>
    public int width
    {
      get => this.m_Width;
      set => this.m_Width = value;
    }

    /// <summary>
    ///   <para>Height of the rectangle.</para>
    /// </summary>
    public int height
    {
      get => this.m_Height;
      set => this.m_Height = value;
    }

    /// <summary>
    ///   <para>Shows the minimum X value of the RectInt.</para>
    /// </summary>
    public int xMin
    {
      get => Math.Min(this.m_XMin, this.m_XMin + this.m_Width);
      set
      {
        int xMax = this.xMax;
        this.m_XMin = value;
        this.m_Width = xMax - this.m_XMin;
      }
    }

    /// <summary>
    ///   <para>Show the minimum Y value of the RectInt.</para>
    /// </summary>
    public int yMin
    {
      get => Math.Min(this.m_YMin, this.m_YMin + this.m_Height);
      set
      {
        int yMax = this.yMax;
        this.m_YMin = value;
        this.m_Height = yMax - this.m_YMin;
      }
    }

    /// <summary>
    ///   <para>Shows the maximum X value of the RectInt.</para>
    /// </summary>
    public int xMax
    {
      get => Math.Max(this.m_XMin, this.m_XMin + this.m_Width);
      set => this.m_Width = value - this.m_XMin;
    }

    /// <summary>
    ///   <para>Shows the maximum Y value of the RectInt.</para>
    /// </summary>
    public int yMax
    {
      get => Math.Max(this.m_YMin, this.m_YMin + this.m_Height);
      set => this.m_Height = value - this.m_YMin;
    }

    /// <summary>
    ///   <para>Returns the position (x, y) of the RectInt.</para>
    /// </summary>
    public Vector2Int position
    {
      get => new Vector2Int(this.m_XMin, this.m_YMin);
      set
      {
        this.m_XMin = value.x;
        this.m_YMin = value.y;
      }
    }

    /// <summary>
    ///   <para>Returns the width and height of the RectInt.</para>
    /// </summary>
    public Vector2Int size
    {
      get => new Vector2Int(this.m_Width, this.m_Height);
      set
      {
        this.m_Width = value.x;
        this.m_Height = value.y;
      }
    }

    /// <summary>
    ///   <para>Sets the bounds to the min and max value of the rect.</para>
    /// </summary>
    /// <param name="minPosition"></param>
    /// <param name="maxPosition"></param>
    public void SetMinMax(Vector2Int minPosition, Vector2Int maxPosition)
    {
      this.min = minPosition;
      this.max = maxPosition;
    }

    public RectInt(int xMin, int yMin, int width, int height)
    {
      this.m_XMin = xMin;
      this.m_YMin = yMin;
      this.m_Width = width;
      this.m_Height = height;
    }

    public RectInt(Vector2Int position, Vector2Int size)
    {
      this.m_XMin = position.x;
      this.m_YMin = position.y;
      this.m_Width = size.x;
      this.m_Height = size.y;
    }

    /// <summary>
    ///   <para>Clamps the position and size of the RectInt to the given bounds.</para>
    /// </summary>
    /// <param name="bounds">Bounds to clamp the RectInt.</param>
    public void ClampToBounds(RectInt bounds)
    {
      this.position = new Vector2Int(Math.Max(Math.Min(bounds.xMax, this.position.x), bounds.xMin), Math.Max(Math.Min(bounds.yMax, this.position.y), bounds.yMin));
      this.size = new Vector2Int(Math.Min(bounds.xMax - this.position.x, this.size.x), Math.Min(bounds.yMax - this.position.y, this.size.y));
    }

    /// <summary>
    ///   <para>Returns true if the given position is within the RectInt.</para>
    /// </summary>
    /// <param name="position">Position to check.</param>
    /// <returns>
    ///   <para>Whether the position is within the RectInt.</para>
    /// </returns>
    public bool Contains(Vector2Int position)
    {
      return position.x >= this.xMin && position.y >= this.yMin && position.x < this.xMax && position.y < this.yMax;
    }

    /// <summary>
    ///   <para>RectInts overlap if each RectInt Contains a shared point.</para>
    /// </summary>
    /// <param name="other">Other rectangle to test overlapping with.</param>
    /// <returns>
    ///   <para>True if the other rectangle overlaps this one.</para>
    /// </returns>
    public bool Overlaps(RectInt other)
    {
      return other.xMin < this.xMax && other.xMax > this.xMin && other.yMin < this.yMax && other.yMax > this.yMin;
    }

    /// <summary>
    ///   <para>Returns the x, y, width and height of the RectInt.</para>
    /// </summary>
    /// <param name="format">A numeric format string.</param>
    /// <param name="formatProvider">An object that specifies culture-specific formatting.</param>
    public override string ToString() => this.ToString((string) null, (IFormatProvider) null);

    /// <summary>
    ///   <para>Returns the x, y, width and height of the RectInt.</para>
    /// </summary>
    /// <param name="format">A numeric format string.</param>
    /// <param name="formatProvider">An object that specifies culture-specific formatting.</param>
    public string ToString(string format) => this.ToString(format, (IFormatProvider) null);

    /// <summary>
    ///   <para>Returns the x, y, width and height of the RectInt.</para>
    /// </summary>
    /// <param name="format">A numeric format string.</param>
    /// <param name="formatProvider">An object that specifies culture-specific formatting.</param>
    public string ToString(string format, IFormatProvider formatProvider)
    {
      if (formatProvider == null)
        formatProvider = (IFormatProvider) CultureInfo.InvariantCulture.NumberFormat;
      return UnityString.Format("(x:{0}, y:{1}, width:{2}, height:{3})", (object) this.x.ToString(format, formatProvider), (object) this.y.ToString(format, formatProvider), (object) this.width.ToString(format, formatProvider), (object) this.height.ToString(format, formatProvider));
    }

    /// <summary>
    ///   <para>Returns true if the given RectInt is equal to this RectInt.</para>
    /// </summary>
    /// <param name="other"></param>
    public bool Equals(RectInt other)
    {
      return this.m_XMin == other.m_XMin && this.m_YMin == other.m_YMin && this.m_Width == other.m_Width && this.m_Height == other.m_Height;
    }

    /// <summary>
    ///   <para>A RectInt.PositionCollection that contains all positions within the RectInt.</para>
    /// </summary>
    public RectInt.PositionEnumerator allPositionsWithin
    {
      get => new RectInt.PositionEnumerator(this.min, this.max);
    }

    /// <summary>
    ///   <para>An iterator that allows you to iterate over all positions within the RectInt.</para>
    /// </summary>
    public struct PositionEnumerator : IEnumerator<Vector2Int>, IEnumerator, IDisposable
    {
      private readonly Vector2Int _min;
      private readonly Vector2Int _max;
      private Vector2Int _current;

      public PositionEnumerator(Vector2Int min, Vector2Int max)
      {
        this._min = this._current = min;
        this._max = max;
        this.Reset();
      }

      /// <summary>
      ///   <para>Returns this as an iterator that allows you to iterate over all positions within the RectInt.</para>
      /// </summary>
      /// <returns>
      ///   <para>This RectInt.PositionEnumerator.</para>
      /// </returns>
      public RectInt.PositionEnumerator GetEnumerator() => this;

      /// <summary>
      ///   <para>Moves the enumerator to the next position.</para>
      /// </summary>
      /// <returns>
      ///   <para>Whether the enumerator has successfully moved to the next position.</para>
      /// </returns>
      public bool MoveNext()
      {
        if (this._current.y >= this._max.y)
          return false;
        ++this._current.x;
        int x1 = this._current.x;
        Vector2Int vector2Int = this._max;
        int x2 = vector2Int.x;
        if (x1 >= x2)
        {
          ref Vector2Int local = ref this._current;
          vector2Int = this._min;
          int x3 = vector2Int.x;
          local.x = x3;
          int x4 = this._current.x;
          vector2Int = this._max;
          int x5 = vector2Int.x;
          if (x4 >= x5)
            return false;
          ++this._current.y;
          int y1 = this._current.y;
          vector2Int = this._max;
          int y2 = vector2Int.y;
          if (y1 >= y2)
            return false;
        }
        return true;
      }

      /// <summary>
      ///   <para>Resets this enumerator to its starting state.</para>
      /// </summary>
      public void Reset()
      {
        this._current = this._min;
        --this._current.x;
      }

      /// <summary>
      ///   <para>Current position of the enumerator.</para>
      /// </summary>
      public Vector2Int Current => this._current;

      object IEnumerator.Current => (object) this.Current;

      void IDisposable.Dispose()
      {
      }
    }
  }
}
